/**
 * RS2Lite, the open source Runescape Launcher
 * Copyright (C) 2012 Nikki <nikki@nikkii.us>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package rs.hyperion.loader;

import java.applet.Applet;
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Robot;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.UIManager;

import rs.hyperion.loader.loader.AppletPanel;
import rs.hyperion.loader.loader.WebAppletLoader;

/**
 * Main Class
 * 
 * @author Nikki
 * @author Tyrone Chicken
 * 
 */
public class Main {

	/**
	 * The application title
	 */
	private static final String APPLICATION_TITLE = "Hyperion Loader";

	/**
	 * The JFrame
	 */
	private JFrame frame;

	/**
	 * The panel which contains the RuneScape Applet/Loading text
	 */
	private AppletPanel panel;

	/**
	 * The robot instance
	 */
	private Robot robot;

	/**
	 * The loader that RuneScape is loaded on
	 */
	private ExecutorService clientService = Executors.newSingleThreadExecutor();

	/**
	 * The loader future
	 */
	private Future<Applet> loaderFuture;

	/**
	 * Initialize the frame
	 * 
	 */
	public void init() {
		frame = new JFrame(APPLICATION_TITLE);
		panel = new AppletPanel();
		panel.setLayout(new BorderLayout());
		frame.add(panel);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.pack();
		frame.setVisible(true);
		frame.setResizable(false);
		
		/**
		 * Used to check for an applet
		 */
		Executors.newSingleThreadExecutor().execute(new Runnable() {
			@Override
			public void run() {
				while (!panel.hasApplet()) {
					panel.paintOverlay();
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		});
		/**
		 * Initialize the robot
		 */
		try {
			robot = new Robot();
		} catch (AWTException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Start the loading process on the RS applet
	 */
	public void load() {
		loaderFuture = clientService.submit(new Callable<Applet>() {
			@Override
			public Applet call() throws Exception {
				int world = new Random().nextInt(78);
				/**
				 * Missing worlds
				 */
				switch (world) {
				case 0:
					world = 1;
					break;
				case 7:
					world = 9;
					break;
				case 8:
					world = 9;
					break;
				case 15:
					world = 17;
					break;
				case 16:
					world = 17;
					break;
				case 23:
					world = 25;
					break;
				case 24:
					world = 25;
					break;
				case 31:
					world = 33;
					break;
				case 32:
					world = 33;
					break;
				case 39:
					world = 41;
					break;
				case 40:
					world = 41;
					break;
				case 47:
					world = 49;
					break;
				case 48:
					world = 49;
					break;
				case 55:
					world = 57;
					break;
				case 56:
					world = 57;
					break;
				case 63:
					world = 65;
					break;
				case 64:
					world = 65;
					break;
				case 71:
					world = 73;
					break;
				case 72:
					world = 73;
					break;
				}
				WebAppletLoader loader = new WebAppletLoader("http://oldschool" + world + ".runescape.com/j1");
				loader.load();
				return loader.newApplet();
			}
		});
	}

	/**
	 * Wait for the loader to finish starting, then add the applet/repack the frame
	 */
	public void start() {
		if (loaderFuture == null) {
			throw new IllegalArgumentException("Loader is not set!");
		}
		try {
			Applet applet = loaderFuture.get();
			applet.setVisible(true);

			/**
			 * Set and add the applet to the panel
			 */
			panel.setApplet(applet);
			panel.add(applet);

			frame.pack();
		} catch (Exception e) {
			JOptionPane.showMessageDialog(frame, "Unable to load RuneScape : "
					+ e);
		}
	}

	/**
	 * Main entry point
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			Main hyperion = new Main();
			/**
			 * Sets the look
			 */
        	JFrame.setDefaultLookAndFeelDecorated(true);
            UIManager.setLookAndFeel("org.jvnet.substance.skin.SubstanceBusinessBlackSteelLookAndFeel");
			/**
			 * Start loading the applet
			 */
			hyperion.load();
			/**
			 * Initialize all other stuff
			 */
			hyperion.init();
			/**
			 * Finally, add the Applet
			 */
			hyperion.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
